package com.reider.log4AS3.core
{
	import com.reider.log4AS3.appenders.Appender;
	import com.reider.log4AS3.dataholder.FormatedMsg;
	import com.reider.log4AS3.dataholder.Level;
	import com.reider.log4AS3.dataholder.Log;
	import com.reider.log4AS3.dataholder.LoggerScope;
	import com.reider.log4AS3.event.ConfigXMLLoaderEvent;
	import com.reider.log4AS3.utils.MessageFormatter;
	import com.reider.log4AS3.utils.ObjectContainer;
	
	import flash.events.Event;
	import flash.events.EventDispatcher;
	
	/**
	 * @private
	 */
	public class LogFilter extends EventDispatcher
	{
		private var xmlLoader:ConfigXMLLoader
		private var appenders:ObjectContainer
		private var loggers:Array
		
		
		//--------------------------------------------------------------------------
	    //
	    //  Constructor
	    //
	    //--------------------------------------------------------------------------
		
		public function LogFilter()
		{
			xmlLoader = new ConfigXMLLoader()
			//xmlLoader.addEventListener(ConfigXMLLoaderEvent.XML_COMPLETE, onConfigCompelete)
		}
		
		//--------------------------------------------------------------------------
	    //
	    //  Public methods
	    //
	    //--------------------------------------------------------------------------
		
		public function loadConfig(url:String):void
		{
			xmlLoader.loadURL(url)
		}
		
		public function addLog(log:Log):void
		{
			var infos:Array = getLoggerInfos(log.level, log.loggerName)
			if(infos){
				for(var i:int=0; i<infos.length; i++){
					addToAppender(infos[i], log)
				}
			}
		}
		
		//--------------------------------------------------------------------------
	    //
	    //  Private methods
	    //
	    //--------------------------------------------------------------------------
		
		private function getLoggerInfos(level:Level, name:String):Array
        {
                var infos:Array = new Array()
                for(var i:int=0; i<loggers.length; i++){
                        var loggerInfo:LoggerScope = loggers[i]
                                
                        if(loggerInfo.isRoot){
                                infos.push(loggerInfo)
                        }else if(loggerInfo.name.length <= name.length){          
                                if(packageEquals(name, loggerInfo.name)){
                                	infos.push(loggerInfo)
                                }
                        }       
                }
                
                return filterLoggerInfos(infos, level);
        }

		
		private function packageEquals(fullName:String, shortName:String):Boolean
		{
			var fullParts:Array = fullName.toUpperCase().split(".")
			var shortParts:Array = shortName.toUpperCase().split(".")
			
			for(var i:int=0; i<shortParts.length; i++){
				if(fullParts[i] != shortParts[i]){
					return false
				}	
			}
			
			return true
		}
		
		private function filterLoggerInfos(infos:Array, level:Level):Array
		{
			var filtered:Array = new Array()
			if(infos.length == 0) return filtered
			
			infos.sort(ifoSorter)
			
			var curLogger:LoggerScope = infos[0]
			filtered[0] = curLogger
			
			for(var i:int=1; i<infos.length; i++){
				var loggerInfo:LoggerScope = infos[i]
				if(loggerInfo.level.priority > curLogger.level.priority ||
				loggerInfo.level.priority < curLogger.level.priority){
					filtered.splice(0)
					filtered.push(loggerInfo)
					curLogger = loggerInfo
				}else{
					filtered.push(loggerInfo)
				}
			}
			
			if(level.priority >= curLogger.level.priority){
				return filtered
			}
			
			return null
		}
		
		private function ifoSorter(a:LoggerScope, b:LoggerScope):Number
		{
			if(a.isRoot){
				return -1
			}else if(b.isRoot){
				return 1
			}else if(a.name.length > b.name.length){
				return 1
			}else if(a.name.length < b.name.length){
				return -1
			}else{
				return 0;
			}
		}
		
		private function addToAppender(loggerInfo:LoggerScope, log:Log):void
		{
			/*if(loggerInfo.appenderNames.length){
				var formatedMsg:FormatedMsg = MessageFormatter.formatString(log.format, log.args)
				log.log_internal::formatedText = formatedMsg.foramtedText
				log.log_internal::additionalArgs = formatedMsg.additonalArgs
				
				for each(var apenderName:String in loggerInfo.appenderNames){
					var appender:Appender = appenders.getObj(apenderName) as Appender
					if(appender){
						appender.addLog(log.clone())
					}
				}
			}*/
		}
		
		//--------------------------------------------------------------------------
	    //
	    //  Callback methods
	    //
	    //--------------------------------------------------------------------------
		
		private function onConfigCompelete(event:ConfigXMLLoaderEvent):void
		{
			/*appenders = event.appenders
			loggers = event.loggers
			
			dispatchEvent(new Event(Event.COMPLETE))*/
		}
	}
}